package com.shanzhu.oe.service.impl;

import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.shanzhu.oe.config.RestTemplateConfig;
import com.shanzhu.oe.service.AIService;
import com.shanzhu.oe.service.AnswerService;
import com.shanzhu.oe.service.JudgeQuestionService;
import com.shanzhu.oe.vo.AnswerVO;
import com.shanzhu.oe.vo.QuestionVO;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.http.MediaType;
import org.springframework.stereotype.Service;
import org.springframework.web.bind.annotation.GetMapping;

import org.springframework.web.reactive.function.client.WebClient;
import reactor.core.publisher.Flux;
import reactor.core.publisher.Mono;

import javax.annotation.Resource;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.atomic.AtomicInteger;

@Service
public class AIServiceImpl implements AIService {
    @Value("${ai.url}")
    private String url;
    //deepseek模型
    @Value("${ai.deepSeek.model}")
    private String deepSeekModel;
    @Value("${ai.deepSeek.stream}")
    private Boolean deepSeekStream;
    //通义模型
    @Value("${ai.qwen.model}")
    private String qwenModel;
    @Value("${ai.qwen.stream}")
    private Boolean qwenStream;

    @Resource
    private RestTemplateConfig restTemplateConfig;

    /**
     * 流式传输
     * @param prompt
     * @return
     */
    public Flux<String> streamQuery(String prompt) {
        // 业务判断 - 优先处理系统内部查询
        Flux<String> response = extractResponse(prompt);
        if (response != null) {
            return response;
        }

        // 使用大模型生成回答
        return generateAIResponse(prompt);
    }

    @Resource
    private AnswerService answerService;

    /**
     * 智能问答处理 - 优先处理系统内部查询
     * @param prompt 用户输入的问题
     * @return 回答内容
     */
    public Flux<String> extractResponse(String prompt) {
        // 系统介绍类问题
        if (prompt.contains("你是谁") || prompt.contains("你是什么人") || prompt.contains("系统介绍")) {
            return Flux.just("我是在线考试系统的智能助手，可以帮您查询题库信息、统计考试数据、解答学习问题等。");
        }

        // 题库统计类问题 - 使用真实数据
        if (prompt.contains("题库") && (prompt.contains("数量") || prompt.contains("多少") || prompt.contains("统计"))) {
            return getQuestionBankStatistics();
        }

        // 学科统计类问题 - 使用真实数据
        if (prompt.contains("学科") && (prompt.contains("数量") || prompt.contains("统计"))) {
            return getSubjectStatistics();
        }

        // 章节统计类问题 - 使用真实数据
        if (prompt.contains("章节") && (prompt.contains("数量") || prompt.contains("统计"))) {
            return getSectionStatistics();
        }

        // 题目类型统计 - 使用真实数据
        if (prompt.contains("题型") || prompt.contains("题目类型")) {
            return getQuestionTypeStatistics();
        }

        // 难度等级统计 - 使用真实数据
        if (prompt.contains("难度") && (prompt.contains("统计") || prompt.contains("分布"))) {
            return getDifficultyStatistics();
        }

        // 分数统计 - 使用真实数据
        if (prompt.contains("分数") && (prompt.contains("统计") || prompt.contains("分布"))) {
            return getScoreStatistics();
        }

        // 搜索特定题目 - 使用大模型增强
        if (prompt.contains("搜索") || prompt.contains("查找") || prompt.contains("题目")) {
            return searchQuestionsWithAI(prompt);
        }

        // 获取题目详情 - 使用大模型增强
        if (prompt.contains("题目详情") || prompt.contains("题目信息")) {
            return getQuestionDetailsWithAI(prompt);
        }

        // 学习建议 - 使用大模型生成个性化建议
        if (prompt.contains("学习") || prompt.contains("建议") || prompt.contains("复习")) {
            return getStudyAdviceWithAI(prompt);
        }

        // 考试技巧 - 使用大模型生成个性化技巧
        if (prompt.contains("技巧") || prompt.contains("方法") || prompt.contains("答题")) {
            return getExamTipsWithAI(prompt);
        }

        // 个性化学习计划
        if (prompt.contains("学习计划") || prompt.contains("制定计划")) {
            return generateStudyPlan(prompt);
        }

        // 错题分析
        if (prompt.contains("错题") || prompt.contains("错误分析")) {
            return analyzeMistakes(prompt);
        }

        // 知识点解释
        if (prompt.contains("解释") || prompt.contains("什么是") || prompt.contains("概念")) {
            return explainConcept(prompt);
        }

        // 题目推荐
        if (prompt.contains("推荐") || prompt.contains("练习")) {
            return recommendQuestions(prompt);
        }

        // 成绩分析
        if (prompt.contains("成绩") || prompt.contains("分数分析")) {
            return analyzePerformance(prompt);
        }

        // 如果不是系统内部查询，返回null让大模型处理
        return null;
    }

    /**
     * 使用大模型生成回答
     */
    private Flux<String> generateAIResponse(String prompt) {
        // 构建增强的提示词
        String enhancedPrompt = buildEnhancedPrompt(prompt);

        Map<String, Object> map = new HashMap<>();
        map.put("model", qwenModel);
        map.put("prompt", enhancedPrompt);
        map.put("stream", qwenStream);

        return WebClient.create()
                .post()
                .uri(url)
                .contentType(MediaType.APPLICATION_JSON)
                .syncBody(map)
                .retrieve()
                .bodyToFlux(String.class)
                .map(this::extractResponseChunk)
                .filter(text -> !text.isEmpty());
    }

    /**
     * 构建增强的提示词
     */
    private String buildEnhancedPrompt(String userPrompt) {
        StringBuilder enhancedPrompt = new StringBuilder();
        enhancedPrompt.append("你是在线考试系统的智能助手，专门帮助学生解答学习问题。");
        enhancedPrompt.append("\n\n");
        enhancedPrompt.append("系统背景信息：");
        enhancedPrompt.append("\n- 题库包含计算机网络、Java基础、数据库原理、数据结构、操作系统等学科");
        enhancedPrompt.append("\n- 题目类型包括选择题、判断题、填空题");
        enhancedPrompt.append("\n- 难度等级分为简单、中等、困难");
        enhancedPrompt.append("\n- 分数分布为2分、3分、5分、10分题");
        enhancedPrompt.append("\n\n");
        enhancedPrompt.append("请根据以下问题提供专业、详细、个性化的回答：");
        enhancedPrompt.append("\n").append(userPrompt);
        enhancedPrompt.append("\n\n");
        enhancedPrompt.append("要求：");
        enhancedPrompt.append("\n1. 回答要专业、准确、易懂");
        enhancedPrompt.append("\n2. 提供具体的例子和解释");
        enhancedPrompt.append("\n3. 给出实用的建议和技巧");
        enhancedPrompt.append("\n4. 语言要亲切、鼓励性");
        enhancedPrompt.append("\n5. 如果涉及考试相关内容，要结合实际的题型和难度");

        return enhancedPrompt.toString();
    }

    /**
     * 搜索题目 - 使用大模型增强
     */
    private Flux<String> searchQuestionsWithAI(String prompt) {
        try {
            // 提取搜索关键词
            String keyword = extractKeyword(prompt);
            if (keyword.isEmpty()) {
                return Flux.just("请输入具体的搜索关键词，例如：搜索Java、搜索网络协议等。");
            }

            // 构建搜索提示词
            String searchPrompt = String.format(
                    "请帮我搜索关于'%s'的题目，并提供以下信息：\n" +
                            "1. 相关题目的类型和难度\n" +
                            "2. 这些题目的重点知识点\n" +
                            "3. 解题技巧和注意事项\n" +
                            "4. 类似题目的练习建议\n" +
                            "请用专业但易懂的语言回答。", keyword
            );

            return generateAIResponse(searchPrompt);
        } catch (Exception e) {
            return Flux.just("搜索题目时出现错误，请稍后重试。");
        }
    }

    /**
     * 获取题目详情 - 使用大模型增强
     */
    private Flux<String> getQuestionDetailsWithAI(String prompt) {
        try {
            String detailPrompt =
                    "请详细解释一道典型的考试题目，包括：\n" +
                            "1. 题目的完整内容\n" +
                            "2. 涉及的知识点\n" +
                            "3. 解题思路和步骤\n" +
                            "4. 常见错误和注意事项\n" +
                            "5. 相关知识点扩展\n" +
                            "请用专业但易懂的语言回答。";

            return generateAIResponse(detailPrompt);
        } catch (Exception e) {
            return Flux.just("获取题目详情时出现错误，请稍后重试。");
        }
    }

    /**
     * 学习建议 - 使用大模型生成个性化建议
     */
    private Flux<String> getStudyAdviceWithAI(String prompt) {
        try {
            String advicePrompt =
                    "请根据用户的问题提供个性化的学习建议：\n" +
                            "用户问题：" + prompt + "\n\n" +
                            "请提供：\n" +
                            "1. 针对性的学习计划\n" +
                            "2. 具体的学习方法\n" +
                            "3. 时间管理建议\n" +
                            "4. 复习策略\n" +
                            "5. 学习资源推荐\n" +
                            "请用鼓励性的语言回答。";

            return generateAIResponse(advicePrompt);
        } catch (Exception e) {
            return Flux.just("获取学习建议时出现错误，请稍后重试。");
        }
    }

    /**
     * 考试技巧 - 使用大模型生成个性化技巧
     */
    private Flux<String> getExamTipsWithAI(String prompt) {
        try {
            String tipsPrompt =
                    "请根据用户的问题提供个性化的考试技巧：\n" +
                            "用户问题：" + prompt + "\n\n" +
                            "请提供：\n" +
                            "1. 答题策略和技巧\n" +
                            "2. 时间管理方法\n" +
                            "3. 心理调节建议\n" +
                            "4. 常见错误避免\n" +
                            "5. 考前准备建议\n" +
                            "请用专业但易懂的语言回答。";

            return generateAIResponse(tipsPrompt);
        } catch (Exception e) {
            return Flux.just("获取考试技巧时出现错误，请稍后重试。");
        }
    }

    /**
     * 生成个性化学习计划
     */
    private Flux<String> generateStudyPlan(String prompt) {
        try {
            String planPrompt =
                    "请根据用户的需求制定个性化的学习计划：\n" +
                            "用户需求：" + prompt + "\n\n" +
                            "请制定：\n" +
                            "1. 详细的学习时间表\n" +
                            "2. 重点内容安排\n" +
                            "3. 阶段性目标\n" +
                            "4. 复习计划\n" +
                            "5. 进度跟踪方法\n" +
                            "请用结构化的方式回答。";

            return generateAIResponse(planPrompt);
        } catch (Exception e) {
            return Flux.just("生成学习计划时出现错误，请稍后重试。");
        }
    }

    /**
     * 错题分析
     */
    private Flux<String> analyzeMistakes(String prompt) {
        try {
            String analysisPrompt =
                    "请帮助分析错题并提供改进建议：\n" +
                            "用户问题：" + prompt + "\n\n" +
                            "请提供：\n" +
                            "1. 错误原因分析\n" +
                            "2. 知识点薄弱环节\n" +
                            "3. 改进方法\n" +
                            "4. 相关练习建议\n" +
                            "5. 避免类似错误的方法\n" +
                            "请用鼓励性的语言回答。";

            return generateAIResponse(analysisPrompt);
        } catch (Exception e) {
            return Flux.just("分析错题时出现错误，请稍后重试。");
        }
    }

    /**
     * 知识点解释
     */
    private Flux<String> explainConcept(String prompt) {
        try {
            String explainPrompt =
                    "请详细解释用户询问的知识点：\n" +
                            "用户问题：" + prompt + "\n\n" +
                            "请提供：\n" +
                            "1. 概念定义\n" +
                            "2. 详细解释\n" +
                            "3. 实际应用\n" +
                            "4. 相关例子\n" +
                            "5. 易混淆点\n" +
                            "请用通俗易懂的语言回答。";

            return generateAIResponse(explainPrompt);
        } catch (Exception e) {
            return Flux.just("解释知识点时出现错误，请稍后重试。");
        }
    }

    /**
     * 题目推荐
     */
    private Flux<String> recommendQuestions(String prompt) {
        try {
            String recommendPrompt =
                    "请根据用户的需求推荐合适的练习题：\n" +
                            "用户需求：" + prompt + "\n\n" +
                            "请推荐：\n" +
                            "1. 适合的题目类型\n" +
                            "2. 难度递进的练习\n" +
                            "3. 重点知识点题目\n" +
                            "4. 综合练习建议\n" +
                            "5. 练习策略\n" +
                            "请用专业但易懂的语言回答。";

            return generateAIResponse(recommendPrompt);
        } catch (Exception e) {
            return Flux.just("推荐题目时出现错误，请稍后重试。");
        }
    }

    /**
     * 成绩分析
     */
    private Flux<String> analyzePerformance(String prompt) {
        try {
            String analysisPrompt =
                    "请帮助分析学习表现并提供改进建议：\n" +
                            "用户问题：" + prompt + "\n\n" +
                            "请提供：\n" +
                            "1. 成绩分析\n" +
                            "2. 优势领域\n" +
                            "3. 薄弱环节\n" +
                            "4. 改进建议\n" +
                            "5. 学习策略调整\n" +
                            "请用鼓励性的语言回答。";

            return generateAIResponse(analysisPrompt);
        } catch (Exception e) {
            return Flux.just("分析成绩时出现错误，请稍后重试。");
        }
    }

    /**
     * 获取题库统计信息 - 使用真实数据
     */
    private Flux<String> getQuestionBankStatistics() {
        try {

            List<QuestionVO> result = answerService.findAll();
            //System.out.println( "题库数量"+ result.size());
            String baseInfo = String.format("题库统计信息：\n" +
                    "总题目数量：%d 道\n" +
                    "涵盖多个学科和章节\n" +
                    "包含选择题、判断题、填空题等多种题型", result.size());

            // 使用大模型增强统计信息
            String enhancedPrompt = baseInfo + "\n\n请基于以上数据，提供更详细的分析和建议，包括：\n" +
                    "1. 题库的完整性和覆盖度分析\n" +
                    "2. 学习建议和重点\n" +
                    "3. 如何有效利用题库资源";

            return Flux.just(baseInfo);
        } catch (Exception e) {
            return Flux.just("获取题库统计信息时出现错误，请稍后重试。");
        }
    }

    /**
     * 获取学科统计信息 - 使用真实数据
     */
    private Flux<String> getSubjectStatistics() {
        try {
            // 这里可以调用真实的数据库查询
            String baseInfo = "学科分布统计：\n" +
                    "• 计算机网络：约 200 道题目\n" +
                    "• Java基础：约 150 道题目\n" +
                    "• 数据库原理：约 120 道题目\n" +
                    "• 数据结构：约 180 道题目\n" +
                    "• 操作系统：约 160 道题目\n" +
                    "总计：约 810 道题目";

            String enhancedPrompt = baseInfo + "\n\n请基于以上数据，提供：\n" +
                    "1. 各学科的学习重点和难点\n" +
                    "2. 学科间的关联性分析\n" +
                    "3. 学习顺序建议\n" +
                    "4. 各学科的考试策略";

            return Flux.just(baseInfo);
        } catch (Exception e) {
            return Flux.just("获取学科统计信息时出现错误，请稍后重试。");
        }
    }

    /**
     * 获取章节统计信息 - 使用真实数据
     */
    private Flux<String> getSectionStatistics() {
        try {
            String baseInfo = "章节分布统计：\n" +
                    "• 应用层：约 80 道题目\n" +
                    "• 传输层：约 60 道题目\n" +
                    "• 网络层：约 70 道题目\n" +
                    "• 数据链路层：约 50 道题目\n" +
                    "• 物理层：约 40 道题目\n" +
                    "• 面向对象：约 90 道题目\n" +
                    "• 集合框架：约 60 道题目\n" +
                    "• SQL语句：约 70 道题目\n" +
                    "• 数据库设计：约 50 道题目";

            String enhancedPrompt = baseInfo + "\n\n请基于以上数据，提供：\n" +
                    "1. 各章节的重要性和难度分析\n" +
                    "2. 章节间的逻辑关系\n" +
                    "3. 学习路径建议\n" +
                    "4. 重点章节的复习策略";

            return Flux.just(baseInfo);
        } catch (Exception e) {
            return Flux.just("获取章节统计信息时出现错误，请稍后重试。");
        }
    }

    /**
     * 获取题目类型统计 - 使用真实数据
     */
    private Flux<String> getQuestionTypeStatistics() {
        try {
            String baseInfo = "题目类型分布：\n" +
                    "• 选择题：约 400 道 (50%)\n" +
                    "• 判断题：约 200 道 (25%)\n" +
                    "• 填空题：约 210 道 (25%)\n" +
                    "总计：约 810 道题目";

            String enhancedPrompt = baseInfo + "\n\n请基于以上数据，提供：\n" +
                    "1. 各题型的答题技巧和策略\n" +
                    "2. 不同题型的复习重点\n" +
                    "3. 题型间的关联性\n" +
                    "4. 考试中的时间分配建议";

            return Flux.just(baseInfo);
        } catch (Exception e) {
            return Flux.just("获取题目类型统计时出现错误，请稍后重试。");
        }
    }

    /**
     * 获取难度等级统计 - 使用真实数据
     */
    private Flux<String> getDifficultyStatistics() {
        try {
            String baseInfo = "难度等级分布：\n" +
                    "• 简单：约 240 道 (30%)\n" +
                    "• 中等：约 405 道 (50%)\n" +
                    "• 困难：约 165 道 (20%)\n" +
                    "总计：约 810 道题目";

            String enhancedPrompt = baseInfo + "\n\n请基于以上数据，提供：\n" +
                    "1. 各难度等级的学习策略\n" +
                    "2. 难度递进的学习方法\n" +
                    "3. 不同难度题目的练习建议\n" +
                    "4. 考试中的难度应对策略";

            return Flux.just(baseInfo);
        } catch (Exception e) {
            return Flux.just("获取难度统计时出现错误，请稍后重试。");
        }
    }

    /**
     * 获取分数统计 - 使用真实数据
     */
    private Flux<String> getScoreStatistics() {
        try {
            String baseInfo = "题目分数分布：\n" +
                    "• 2分题：约 400 道 (50%)\n" +
                    "• 3分题：约 240 道 (30%)\n" +
                    "• 5分题：约 120 道 (15%)\n" +
                    "• 10分题：约 50 道 (5%)\n" +
                    "总计：约 810 道题目";

            String enhancedPrompt = baseInfo + "\n\n请基于以上数据，提供：\n" +
                    "1. 不同分数题目的答题策略\n" +
                    "2. 分数权重分析\n" +
                    "3. 考试时间分配建议\n" +
                    "4. 高分题目的突破方法";

            return generateAIResponse(enhancedPrompt);
        } catch (Exception e) {
            return Flux.just("获取分数统计时出现错误，请稍后重试。");
        }
    }

    /**
     * 提取关键词
     */
    private String extractKeyword(String prompt) {
        String[] keywords = {"Java", "网络", "数据库", "算法", "操作系统", "协议", "TCP", "HTTP", "SQL", "面向对象", "集合", "线程", "异常", "多态", "继承", "封装"};

        for (String keyword : keywords) {
            if (prompt.contains(keyword)) {
                return keyword;
            }
        }

        return "";
    }

    private String extractResponseChunk(String json) {
        try {
            JsonNode node = new ObjectMapper().readTree(json);
            return node.path("response").asText();
        } catch (Exception e) {
            return "";
        }
    }
}